package cn.hpu.mobile_bank.service.impl;

import cn.hpu.mobile_bank.domain.Account;
import cn.hpu.mobile_bank.domain.TransRecord;
import cn.hpu.mobile_bank.dto.req.SelectTransRecordReq;
import cn.hpu.mobile_bank.dto.req.TransferFormReq;
import cn.hpu.mobile_bank.dto.resp.*;
import cn.hpu.mobile_bank.exception.BusinessException;
import cn.hpu.mobile_bank.mapper.AccountMapper;
import cn.hpu.mobile_bank.mapper.TransRecordMapper;
import cn.hpu.mobile_bank.service.TransRecordService;
import cn.hpu.mobile_bank.utils.RequestHolder;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author DELL
 * @description 针对表【transrecord】的数据库操作Service实现
 * @createDate 2024-06-20 17:16:33
 */
@Service
public class TransRecordServiceImpl extends ServiceImpl<TransRecordMapper, TransRecord>
        implements TransRecordService {

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private TransRecordMapper transRecordMapper;

    @Transactional
    @Override
    public ApiResult<String> transfer(TransferFormReq transferFormReq) {
        String accountId = transferFormReq.getAccountId();
        String accountName = transferFormReq.getAccountName();
        String amount = transferFormReq.getAmount();
        String password = transferFormReq.getPassword();
        String recepName = transferFormReq.getRecepName();
        String recepAccount = transferFormReq.getRecepAccount();
        String telephone = RequestHolder.get().getTelephone();

        //校验账户是否存在
        Account account = accountMapper.selectByTelephoneAndAccountId(telephone, Integer.parseInt(accountId));
        Account recipient = accountMapper.selectByPersonNameAndAccountName(recepAccount, recepName);
        if (account == null || recipient == null || !account.getAccountName().equals(accountName)) {
            throw new BusinessException("账户不存在");
        }
        //校验密码
        if (!account.getPassword().equals(password)) {
            throw new BusinessException("密码错误");
        }

        //保证线程安全
        synchronized (this) {
            //校验余额
            if (account.getBalance().compareTo(new BigDecimal(amount)) < 0) {
                throw new BusinessException("余额不足");
            }
            //转帐方扣减余额
            account.setBalance(account.getBalance().subtract(new BigDecimal(amount)));
            accountMapper.updateById(account);
        }

        //收款方增加余额
        recipient.setBalance(recipient.getBalance().add(new BigDecimal(amount)));
        accountMapper.updateById(recipient);

        //存入转账记录
        TransRecord transRecord = new TransRecord();
        transRecord.setAccountId(Integer.parseInt(accountId));
        transRecord.setOtherId(recipient.getId());
        transRecord.setMoney(new BigDecimal(amount));
        transRecord.setTranstypeId(2);
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d");
        // 获取当前日期
        String formattedDate = LocalDate.now().format(formatter);
        transRecord.setTransDate(formattedDate);

        transRecordMapper.insert(transRecord);
        return ApiResult.success();
    }

    @Override
    public ApiResult<TransferRecordResponse> record(Integer id) {
        List<Account> accounts = accountMapper.selectByTelephone(RequestHolder.get().getTelephone());
        Account account = accountMapper.selectById(id);
        if (!accounts.contains(account)) {
            throw new RuntimeException("该用户没有此账户");
        }

        List<TransRecord> transRecords = transRecordMapper.selectByAccountId(id);
        List<TransRecord> transRecords2 = transRecordMapper.selectByOtherId(id);
        //总支出
        BigDecimal expense = transRecords.stream().map(TransRecord::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        //总收入
        BigDecimal income = transRecords2.stream().map(TransRecord::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        //交易记录 转给别人的
        List<TransRecordList> transRecordList = transRecordMapper.getTransRecordListByAccountIdToOthers(id);
        transRecordList.stream().forEach(tr -> {
            tr.setMoney("-" + tr.getMoney());
        });

        //交易记录 收到的
        List<TransRecordList> transRecordList2 = transRecordMapper.getTransRecordListByOtherIdToMe(id);
        transRecordList2.stream().forEach(tr -> {
            tr.setMoney("+" + tr.getMoney());
        });

        transRecordList.addAll(transRecordList2);
        //按照transDate倒序排序
        transRecordList.sort(Comparator.comparing(TransRecordList::getTransDate).reversed());

        TransferRecordResponse transferRecordResponse = new TransferRecordResponse();
        transferRecordResponse.setTransRecordList(transRecordList);
        transferRecordResponse.setExpense(expense);
        transferRecordResponse.setIncome(income);
        transferRecordResponse.setBalance(account.getBalance());

        return ApiResult.success(transferRecordResponse);
    }

    @Override
    public ApiResult<AllInAndOutResponse> getAll() {
        //获取该用户下的所有账户
        List<Account> accounts = accountMapper.selectByTelephone(RequestHolder.get().getTelephone());

        BigDecimal AllExpense = BigDecimal.ZERO;
        BigDecimal AllIncome = BigDecimal.ZERO;
        BigDecimal AllBalance = BigDecimal.ZERO;

        for (Account account : accounts) {
            List<TransRecord> transRecords = transRecordMapper.selectByAccountId(account.getId());
            List<TransRecord> transRecords2 = transRecordMapper.selectByOtherId(account.getId());
            //单个银行卡支出
            BigDecimal expense = transRecords.stream().map(TransRecord::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
            AllExpense = AllExpense.add(expense);
            //单个银行卡收入
            BigDecimal income = transRecords2.stream().map(TransRecord::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
            AllIncome = AllIncome.add(income);
            //总资产
            AllBalance = AllBalance.add(account.getBalance());
        }

        AllInAndOutResponse allInAndOutResponse = new AllInAndOutResponse();
        allInAndOutResponse.setBalance(AllBalance);
        allInAndOutResponse.setExpense(AllExpense);
        allInAndOutResponse.setIncome(AllIncome);
        allInAndOutResponse.setAccountNum(accounts.size());

        return ApiResult.success(allInAndOutResponse);
    }

//    @Override
//    public ApiResult<List<TransRecordList>> getAllAccountRecord(SelectTransRecordReq selectTransRecordReq) {
//        String beginDate = selectTransRecordReq.getBeginDate();
//        String endDate = selectTransRecordReq.getEndDate();
//        String realname = selectTransRecordReq.getRealname();
//        String minValue = selectTransRecordReq.getMinValue();
//        String maxValue = selectTransRecordReq.getMaxValue();
//        String accountName = selectTransRecordReq.getAccountName();
//
//        Integer personId = RequestHolder.get().getPersonId();
//
//        //该用户转给他人的转账信息
//        List<TransRecord> transRecordList = transRecordMapper.getRecordToOther(personId, beginDate, endDate, minValue, maxValue);
//        //别人转给该用户的转账信息
//        List<TransRecord> transRecordList2 = transRecordMapper.getRecordToMe(personId, beginDate, endDate, minValue, maxValue);
//
//        List<TransRecordList> collect = transRecordList.stream().map(
//                transRecord -> {
//                    //根据账户id获取账户name和realname
//                    AccountNameAndRealNameDto dto = accountMapper.selectByAccountId(transRecord.getOtherId(), realname, accountName);
//                    if (ObjectUtils.isEmpty(dto)) {
//                        return null;
//                    }
//                    TransRecordList result = new TransRecordList();
//                    result.setMoney("-" + transRecord.getMoney());
//                    result.setTransDate(transRecord.getTransDate());
//                    result.setRealName(dto.getRealName());
//                    result.setAccountName(dto.getAccountName());
//                    result.setTransTypeId(transRecord.getTranstypeId().toString());
//                    return result;
//                }
//        ).filter(Objects::nonNull).collect(Collectors.toList());
//
//        collect.addAll(transRecordList2.stream().map(
//                transRecord -> {
//                    //根据账户id获取账户name和realname
//                    AccountNameAndRealNameDto dto = accountMapper.selectByAccountId(transRecord.getOtherId(), realname, accountName);
//                    if (ObjectUtils.isEmpty(dto)) {
//                        return null;
//                    }
//                    TransRecordList result = new TransRecordList();
//                    result.setMoney("+" + transRecord.getMoney());
//                    result.setTransDate(transRecord.getTransDate());
//                    result.setRealName(dto.getRealName());
//                    result.setAccountName(dto.getAccountName());
//                    result.setTransTypeId(transRecord.getTranstypeId().toString());
//                    return result;
//                }
//        ).filter(Objects::nonNull).collect(Collectors.toList()));
//
//        //按照transDate倒序排序
//        collect.sort(Comparator.comparing(TransRecordList::getTransDate).reversed());
//        return ApiResult.success(collect);
//    }

    @Override
    public ApiResult<List<TransRecordList>> getAllAccountRecord(SelectTransRecordReq selectTransRecordReq) {
        String beginDate = selectTransRecordReq.getBeginDate();
        String endDate = selectTransRecordReq.getEndDate();
        String realname = selectTransRecordReq.getRealname();
        String minValue = selectTransRecordReq.getMinValue();
        String maxValue = selectTransRecordReq.getMaxValue();
        String accountName = selectTransRecordReq.getAccountName();

        List<TransRecordList> result = new ArrayList<>();

        //获取该用户的所有账户
        List<Account> accounts = accountMapper.selectByTelephone(RequestHolder.get().getTelephone());
        accounts.stream().forEach(account -> {
            //交易记录 转给别人的
            List<TransRecordList> transRecordList = transRecordMapper.getTransRecordListByAccountIdToOthers(account.getId());
            transRecordList.stream().forEach(tr -> {
                tr.setMyAccount(account.getAccountName());
                tr.setMoney("-" + tr.getMoney());
            });

            //交易记录 收到的
            List<TransRecordList> transRecordList2 = transRecordMapper.getTransRecordListByOtherIdToMe(account.getId());
            transRecordList2.stream().forEach(tr -> {
                tr.setMyAccount(account.getAccountName());
                tr.setMoney("+" + tr.getMoney());
            });
            result.addAll(transRecordList);
            result.addAll(transRecordList2);
        });


        // 过滤时间
        List<TransRecordList> collect1 = result.stream().filter(transRecordList -> {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = formatter.parse(transRecordList.getTransDate());
                if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate)) {
                    return date.after(formatter.parse(beginDate)) && date.before(formatter.parse(endDate));
                } else if (StringUtils.isNotBlank(beginDate)) {
                    return date.after(formatter.parse(beginDate));
                } else if (StringUtils.isNotBlank(endDate)) {
                    return date.before(formatter.parse(endDate));
                }
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            return true;
        }).collect(Collectors.toList());


        //过滤金额
        List<TransRecordList> collect2 = collect1.stream().filter(transRecordList -> {
            //过滤金额
            BigDecimal money = new BigDecimal(transRecordList.getMoney().substring(1));
            if (StringUtils.isNotBlank(minValue) && StringUtils.isNotBlank(maxValue)) {
                return money.compareTo(new BigDecimal(minValue)) >= 0 && money.compareTo(new BigDecimal(maxValue)) <= 0;
            } else if (StringUtils.isNotBlank(minValue)) {
                return money.compareTo(new BigDecimal(minValue)) >= 0;
            } else if (StringUtils.isNotBlank(maxValue)) {
                return money.compareTo(new BigDecimal(maxValue)) <= 0;
            }
            return true;
        }).collect(Collectors.toList());

        //过滤realname
        List<TransRecordList> collect3 = collect2.stream().filter(transRecordList -> {
            if (StringUtils.isNotBlank(realname)) {
                return transRecordList.getRealName().contains(realname);
            }
            return true;
        }).collect(Collectors.toList());

        //过滤accountName
        List<TransRecordList> collect4 = collect3.stream().filter(transRecordList -> {
            if (StringUtils.isNotBlank(accountName)) {
                return transRecordList.getMyAccount().contains(accountName);
            }
            return true;
        }).collect(Collectors.toList());

        collect4.sort(Comparator.comparing(TransRecordList::getTransDate).reversed());
        return ApiResult.success(collect4);
    }
}




